package rpg.ai;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.Timer;

import rpg.Rpg;
import rpg.map.Creature;
import square.ai.AI;

/**
 * 
 * @author Pedro Silva Moreira
 */
public class NpcAI implements ActionListener, AI {
	private Creature creature;
	private int thinksPerSecond = 10;
	private Timer thinkTimer;

	// Creation'
	public NpcAI(Creature creature) {
		creature.setIntelligence(this);
		this.setCreature(creature);
		thinkTimer = new Timer(1000 / getThinksPerSecond(), this);
	}

	// Think
	public void startThink() {
		if (Rpg.disableEvents)
			return;
		thinkTimer.start();
	}

	// Event
	@Override
	public void onThink(Integer time) {
		if (getCreature().getIntelligence() != this) {
			getThinkTimer().stop();
			return;
		}

		if (getCreature().getScript() != null) {
			if (!getCreature().getScript().onThink(time)) {
				return;
			}
		}

		if (getCreature().getTarget() != null) {
			if (getCreature().getTarget().getLocation()
					.distance(getCreature().getLocation(), false) > this
					.getCreature().getData().getRange()) {
				this.getCreature().onTarget(null);
			}
		}

		// Target
		if (getCreature().getTargetOf().size() > 0) {
			Integer nearDistance = null;
			Creature nearCreature = null;
			
			for(Creature it : getCreature().getTargetOf()) {
				int thisDistance = this.getCreature().getLocation().distance(it.getLocation(), true);
				if(nearDistance == null || thisDistance > nearDistance) {
					nearDistance = thisDistance;
					nearCreature = it;
				}
			}
			
			if(this.getCreature().onTarget(nearCreature))
				this.getCreature().onTarget(nearCreature);
		} else {
			if (getCreature().getData().getAggressive()) {
				Creature target = creature.getLocation().nearCreature("",
						getCreature().getData().getRange(), true);

				if (getCreature().getTarget() == null && target != null
						&& getCreature().onTarget(target)) {
					getCreature().onTarget(target);
				}
			}
		}

		// Follow
		String follow = getCreature().getData().getFollow();
		if (!follow.equals("none") && getCreature().getTarget() != null) {
			if (follow.equals("follow")) {
				getCreature().walkTo(getCreature().getTarget().getLocation(),
						false);
			} else if (follow.equals("escape")) {
				getCreature().walkTo(getCreature().getTarget().getLocation(),
						true);
			} else if (follow.startsWith("distance(")) {
				int distance = getCreature().getTarget().getLocation()
						.distance(this.getCreature().getLocation(), true);
				int perfectDistance = Integer.valueOf(follow.substring(9,
						follow.length() - 1));

				if (distance > perfectDistance) {
					getCreature().walkTo(
							getCreature().getTarget().getLocation(), false);
				} else if (distance < perfectDistance) {
					getCreature().walkTo(
							getCreature().getTarget().getLocation(), true);
				}
			}
		}

		// Skill
		if (this.getCreature().getTarget() != null) {
			this.getCreature()
					.randomSkill(this.getCreature().getTarget(), true);
		}
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		onThink(1000 / getThinksPerSecond());
	}

	// Get & Set
	public Creature getCreature() {
		return creature;
	}

	public final void setCreature(Creature creature) {
		this.creature = creature;
	}

	public final int getThinksPerSecond() {
		return thinksPerSecond;
	}

	public void setThinksPerSecond(int thinksPerSecond) {
		this.thinksPerSecond = thinksPerSecond;
	}

	public Timer getThinkTimer() {
		return thinkTimer;
	}

	public void setThinkTimer(Timer thinkTimer) {
		this.thinkTimer = thinkTimer;
	}
}
